﻿using System;
using System.Collections.Generic;
using System.Drawing;
using Semantics;

namespace GraphBase.Presentation
{
    public class GraphPositionView : IGraphPositionView
    {
        public GraphView GraphView;
        IGraph GraphDatabase;
        GraphPositionManager GraphPositionManager;
        GraphGraphUserControl GraphGraphUserControl;
        NodePos SelectedNode;
        EdgePos SelectedLineEdge;
        EdgePos SelectedArcEdge;
        GraphbaseObjectManager ObjectManager;
        public GraphPositionView(GraphPositionManager manager, GraphGraphUserControl graphgraphusercontrol)
        {
            GraphPositionManager = manager;
            GraphGraphUserControl = graphgraphusercontrol;
            GraphDatabase = graphgraphusercontrol.Graph;
            ObjectManager = new GraphbaseObjectManager((IManagedGraphBase)this.GraphDatabase);
            //NodePositions=
        }
        public SortedList<int, NodePos> NodePositions = new SortedList<int, NodePos>();
        public SortedList<int, EdgePos> EdgeLines = new SortedList<int, EdgePos>();
        public List<Node> ViewNodes()
        {
            List<Node> viewNodes = new List<Node>();
            foreach (NodePos np in NodePositions.Values)
            {
                viewNodes.Add(np.pNode);
            }
            return viewNodes;
        }
        public List<Edge> ViewEdges()
        {
            List<Edge> viewEdges = new List<Edge>();
            foreach (EdgePos ep in EdgeLines.Values)
            {
                viewEdges.Add(ep.pedge);
            }
            return viewEdges;
        }

        void LoadGraphView()
        {
        }
        public void LoadGraphView(Node viewtype)
        {
            NodePositions.Clear();
            EdgeLines.Clear();
            GraphView = this.ObjectManager.GetGraphView(viewtype);
            //根据边类型edgetype找到所有关系节点为edgetype的边及边上的节点集
            SortedList<int, Edge> edgesofedgetype = new SortedList<int, Edge>();
            List<Node> nodesofedgetype = new List<Node>();
            nodesofedgetype = new List<Node>();
            nodesofedgetype.AddRange(GraphView.Nodes.Values);
            edgesofedgetype = GraphView.Edges;
            this.PrepareViewGraph(nodesofedgetype, edgesofedgetype);
        }
        void PrepareViewGraph(List<Node> nodes, SortedList<int, Edge> edges)
        {
            this.GraphPositionManager.PrepareDrawingNodesGraph(nodes);
            List<Edge> tmpedges = new List<Edge>();
            foreach (Edge edge in edges.Values)
            {
                tmpedges.Add(edge);
            }
            this.GraphPositionManager.PrepareLineEdges(tmpedges);
            NodePositions = GraphPositionManager.NodePositions;
            EdgeLines = GraphPositionManager.EdgeLines;
        }

        public void LoadGraphView(GraphView graphview)
        {
            List<Edge> tmpedges = new List<Edge>();
            foreach (Edge edge in graphview.Edges.Values)
            {
                tmpedges.Add(edge);
            }
            this.GraphPositionManager.PrepareLineEdges(tmpedges);
            //this.PrepareViewGraph(graphview.Nodes, graphview.Edges);
        }
        public void DrawGraphView(Graphics g, SearchEngine.EnumSearchManner searchmanner)
        {
            SelectedNode = GraphPositionManager.SelectedNodePos;
            SelectedLineEdge = GraphPositionManager.SelectedLineEdge;
            SelectedArcEdge = GraphPositionManager.SelectedArcEdge;
            this.DrawNodes(g, searchmanner);
            this.DrawEdges(g, searchmanner);
        }

        void DrawNodes(Graphics g, SearchEngine.EnumSearchManner searchmanner)
        {
            DrawAllNodes(g);
            switch (searchmanner)
            {
                case SearchEngine.EnumSearchManner.ByNeightbor:
                    //DrawAllNeighbor(g,gguc.HopDistance);
                    if (SelectedNode != null)
                        DrawNeighbor(g, this.SelectedNode, GraphGraphUserControl.HopDistance);
                    break;
                case SearchEngine.EnumSearchManner.All:
                default:

                    DrawSelected(g);
                    break;
            }
        }
        void DrawAllNodes(Graphics g)
        {
            foreach (NodePos npos in this.NodePositions.Values)
            {
                try
                {
                    //默认节点为暗蓝色
                    npos.DrawColorNodes(g, npos.pNode.Label, npos.cPoint, -1);
                }
                catch (Exception exp)
                {
                    g.DrawString(exp.ToString(), new Font(FontFamily.GenericSansSerif, 10.0f), new SolidBrush(Color.DarkBlue), 10, 10);
                }
            }
        }
        void DrawNeighbor(Graphics g, NodePos origin, int distance)
        {
            try
            {
                this.Search(distance, origin);
                for (int j = 0; j < this.Neighbors.Count; j++)
                {
                    SortedList<int, NodePos> level = this.Neighbors[j];
                    foreach (NodePos npos in level.Values)
                    {
                        npos.DrawColorNodes(g, npos.pNode.Label, npos.cPoint, j);
                        //选中直线
                        if (SelectedLineEdge != null)
                        {
                            if (SelectedNode != null)
                            {
                                if (npos.pNode.Id == SelectedNode.pNode.Id)//选中节点显示黄色
                                    npos.DrawColorNodes(g, SelectedNode.pNode.Label, SelectedNode.cPoint, 0);
                            }
                            else
                            {
                                if ((SelectedLineEdge.pedge.Incoming.Label == npos.pNode.Label) || (SelectedLineEdge.pedge.Outgoing.Label == npos.pNode.Label))
                                    npos.DrawColorNodes(g, npos.pNode.Label, npos.cPoint, 0);//黄色
                            }
                        }
                        //选中圆弧
                        if (SelectedArcEdge != null)
                        {
                            if (SelectedNode != null)
                            {
                                if (npos.pNode.Id == SelectedNode.pNode.Id)//选中节点显示黄色
                                    npos.DrawColorNodes(g, SelectedNode.pNode.Label, SelectedNode.cPoint, 0);
                            }
                            else
                            {
                                if ((SelectedArcEdge.pedge.Outgoing.Label == npos.pNode.Label) || (SelectedArcEdge.pedge.Incoming.Label == npos.pNode.Label))
                                    npos.DrawColorNodes(g, npos.pNode.Label, npos.cPoint, 0);//黄色
                            }
                        }
                        //选中多个节点
                        if (this.GraphGraphUserControl.GetSelectedMultipleNodes() != null)
                        {
                            foreach (NodePos np in this.GraphGraphUserControl.GetSelectedMultipleNodes())
                            {
                                npos.DrawColorNodes(g, np.pNode.Label, np.cPoint, 0);//黄色
                            }
                        }
                    }
                }
            }
            catch (Exception exp)
            {
                g.DrawString(exp.ToString(), new Font(FontFamily.GenericSansSerif, 10.0f), new SolidBrush(Color.DarkBlue), 10, 10);
            }
        }
        void DrawSelected(Graphics g)
        {
            foreach (NodePos npos in this.NodePositions.Values)
            {
                try
                {
                    //选中节点不为空
                    if (this.SelectedNode != null)
                    {
                        if (npos.pNode.Id == SelectedNode.pNode.Id)//选中节点显示黄色
                        {
                            npos.DrawColorNodes(g, SelectedNode.pNode.Label, SelectedNode.cPoint, 0);
                            npos.DrawSelectedRectangle(g);
                        }
                    }
                    //选中直线
                    if (SelectedLineEdge != null)
                    {
                        if (SelectedNode != null)
                        {
                            if (npos.pNode.Id == SelectedNode.pNode.Id)//选中节点显示黄色
                                npos.DrawColorNodes(g, SelectedNode.pNode.Label, SelectedNode.cPoint, 0);
                        }
                        else
                        {
                            if ((SelectedLineEdge.pedge.Incoming.Label == npos.pNode.Label) || (SelectedLineEdge.pedge.Outgoing.Label == npos.pNode.Label))
                                npos.DrawColorNodes(g, npos.pNode.Label, npos.cPoint, 0);//黄色
                        }
                    }
                    //选中圆弧
                    if (SelectedArcEdge != null)
                    {
                        if (SelectedNode != null)
                        {
                            if (npos.pNode.Id == SelectedNode.pNode.Id)//选中节点显示黄色
                                npos.DrawColorNodes(g, SelectedNode.pNode.Label, SelectedNode.cPoint, 0);
                        }
                        else
                        {
                            if ((SelectedArcEdge.pedge.Outgoing.Label == npos.pNode.Label) || (SelectedArcEdge.pedge.Incoming.Label == npos.pNode.Label))
                                npos.DrawColorNodes(g, npos.pNode.Label, npos.cPoint, 0);//黄色
                        }
                    }
                    //选中多个节点
                    if (this.GraphGraphUserControl.GetSelectedMultipleNodes().Count > 0)
                    {
                        foreach (NodePos np in this.GraphGraphUserControl.GetSelectedMultipleNodes())
                        {
                            npos.DrawColorNodes(g, np.pNode.Label, np.cPoint, 0);//黄色
                        }
                    }
                    else
                        npos.DrawColorNodes(g, npos.pNode.Label, npos.cPoint, -1);
                }
                catch (Exception exp)
                {
                    g.DrawString(exp.ToString(), new Font(FontFamily.GenericSansSerif, 10.0f), new SolidBrush(Color.DarkBlue), 10, 10);
                }
            }
        }

        void DrawEdges(Graphics g, SearchEngine.EnumSearchManner manner)
        {
            DrawAllEdges(g);
            switch (manner)
            {
                case SearchEngine.EnumSearchManner.ByNeightbor:
                    DrawAllNeighborEdges(g, Neighbors);
                    if (SelectedNode != null)
                        DrawNeighborEdges(g, Neighbors);
                    break;
                case SearchEngine.EnumSearchManner.All:
                default:
                    DrawSelectedEdges(g);
                    break;
            }
        }
        void DrawAllEdges(Graphics g)
        {
            //默认边为黑色
            try
            {
                //画直线
                foreach (EdgePos epline in this.EdgeLines.Values)
                {
                    epline.DrawColorLineEdges(g, epline, -1);
                }
                //画弧线
                /*foreach (EdgePt edgepot in this.EdgePoints.Values)
                {
                    edgepot.DrawColorArcEdges(g, edgepot, -1);
                }*/
            }
            catch (Exception exp)
            {
                g.DrawString(exp.ToString(), new Font(FontFamily.GenericSansSerif, 10.0f), new SolidBrush(Color.DarkBlue), 10, 10);
            }
        }
        void DrawSelectedEdges(Graphics g)
        {
            try
            {
                //选中直线
                if (SelectedLineEdge != null)
                {
                    SelectedLineEdge.DrawColorLineEdges(g, SelectedLineEdge, 0);
                }
                //选中圆弧
                if (SelectedArcEdge != null)
                {
                    SelectedArcEdge.DrawColorArcEdges(g, SelectedArcEdge, 0);
                }
            }
            catch (Exception exp)
            {
                g.DrawString(exp.ToString(), new Font(FontFamily.GenericSansSerif, 10.0f), new SolidBrush(Color.DarkBlue), 10, 10);
            }
        }
        void DrawAllNeighborEdges(Graphics g, List<SortedList<int, NodePos>> neighbors)
        {
            NodePosSearchEngine engine = new NodePosSearchEngine(this.GraphDatabase, this.GraphPositionManager);
            List<SortedList<int, List<Edge>>> neighborsEdges = engine.Edges(neighbors);
            try
            {
                foreach (SortedList<int, List<Edge>> level in neighborsEdges)
                {
                    foreach (List<Edge> edges in level.Values)
                    {
                        foreach (Edge edge in edges)
                        {
                            if (EdgeLines.Count > 0)
                            {
                                foreach (EdgePos edgept in EdgeLines.Values)
                                {
                                    if (edgept.pedge == edge)
                                    {
                                        edgept.DrawColorLineEdges(g, edgept, -1);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception exp)
            {
                g.DrawString(exp.ToString(), new Font(FontFamily.GenericSansSerif, 10.0f), new SolidBrush(Color.DarkBlue), 10, 10);
            }
        }
        void DrawNeighborEdges(Graphics g, List<SortedList<int, NodePos>> neighbors)
        {
            NodePosSearchEngine engine = new NodePosSearchEngine(GraphDatabase, this.GraphPositionManager);
            List<SortedList<int, List<Edge>>> neighborsEdges = engine.Edges(neighbors);
            try
            {
                for (int j = 0; j < neighborsEdges.Count; j++)
                {
                    SortedList<int, List<Edge>> level = neighborsEdges[j];
                    foreach (List<Edge> edges in level.Values)
                    {
                        foreach (Edge edge in edges)
                        {
                            if (EdgeLines.Count > 0)
                            {
                                foreach (EdgePos edgept in EdgeLines.Values)
                                {
                                    if (edgept.pedge == edge)
                                    {
                                        edgept.DrawColorLineEdges(g, edgept, j + 1);
                                        break;
                                    }
                                }
                            }
                            //EdgePt edgept=this.PrepareEdge(edge);
                        }
                    }
                }
            }
            catch (Exception exp)
            {
                g.DrawString(exp.ToString(), new Font(FontFamily.GenericSansSerif, 10.0f), new SolidBrush(Color.DarkBlue), 10, 10);
            }
        }


        List<SortedList<int, NodePos>> Neighbors = new List<SortedList<int, NodePos>>();
        public void Search(int distance, NodePos origin)
        {
            NodePosSearchEngine engine = new NodePosSearchEngine(this.GraphDatabase, this.GraphPositionManager);
            this.Neighbors = engine.Search(distance, origin);
            if (Neighbors.Count == 0)
            {
                this.GraphGraphUserControl.Refresh();
            }
        }
        /*public void ShowGraphbaseViewWithGraphGraph(Node viewtype)
        {
            NodePositions.Clear();
            EdgeLines.Clear();
            GraphView = this.GraphPositionManager.GraphDatabase.ObjectManager.GetGraphView(viewtype);
            //根据边类型edgetype找到所有关系节点为edgetype的边及边上的节点集
            SortedList<int, Edge> edgesofedgetype = new SortedList<int, Edge>();
            List<Node> nodesofedgetype = new List<Node>();
            nodesofedgetype = GraphView.Nodes;
            edgesofedgetype = GraphView.Edges;
            this.PrepareViewGraph(nodesofedgetype, edgesofedgetype);
         }*/ 
    }
}
